package ro.dta.idbi.model.dynamicpattern;

/**
 * Vertex class, used to represent a vertex in a graph
 * 
 * @author Tudor Dobrila
 * 
 */
class Vertex {

	/**
	 * Label of the vertex
	 */
	private int id;

	/**
	 * Edges leaving from this vertex
	 */
	private Edge[] outEdges;

	/**
	 * Edges entering in this vertex
	 */
	private Edge[] inEdges;

	/**
	 * Index of the last assign outbound edge
	 */
	private int crtOutEdge;

	/**
	 * Index of the last assign inbound edge
	 */
	private int crtInEdge;

	/**
	 * Vertex class constructor
	 * 
	 * @param id
	 *            Label of the vertex
	 * @param outEdges
	 *            Number of outbound edges
	 * @param inEdges
	 *            Number of inbound edges
	 */
	public Vertex(int id, int outEdges, int inEdges) {
		this.id = id;
		this.outEdges = new Edge[outEdges];
		this.inEdges = new Edge[inEdges];
		this.crtOutEdge = 0;
		this.crtInEdge = 0;
	}

	/**
	 * Add an outbound edge to this vertex
	 * 
	 * @param edge
	 *            Outbound edge to add to this vertex
	 */
	public void addOutEdge(Edge edge) {
		if (crtOutEdge < outEdges.length && edge.getSource() == this) {
			outEdges[crtOutEdge++] = edge;
		}
	}

	/**
	 * Add an inbound edge to this vertex
	 * 
	 * @param edge
	 *            Inbound edge to add to this vertex
	 */
	public void addInEdge(Edge edge) {
		if (crtInEdge < inEdges.length && edge.getTarget() == this) {
			inEdges[crtInEdge++] = edge;
		}
	}

	/**
	 * Get the outbound edge at the specified index
	 * 
	 * @param index
	 *            Index of the outbound edge
	 * @return Edge at the specified index, null if the index is out of bounds
	 */
	public Edge getOutEdge(int index) {
		if (index >= 0 && index < crtOutEdge) {
			return outEdges[index];
		}

		return null;
	}

	/**
	 * Get the inbound edge at the specified index
	 * 
	 * @param index
	 *            Index of the inbound edge
	 * @return Edge at specified index, null if the index is out of bounds
	 */
	public Edge getInEdge(int index) {
		if (index >= 0 && index < crtInEdge) {
			return inEdges[index];
		}

		return null;
	}

	/**
	 * Get the number of outbound edges leaving from this vertex
	 * 
	 * @return Number of outbound edges leaving from this vertex
	 */
	public int getOutEdgeCount() {
		return outEdges.length;
	}

	/**
	 * Get the number of inbound edges entering this vertex
	 * 
	 * @return Number of inbound edges entering this vertex
	 */
	public int getInEdgeCount() {
		return inEdges.length;
	}

	/**
	 * Set the label of the vertex
	 * 
	 * @param id
	 *            New value for the label of the vertex
	 */
	public void setId(int id) {
		this.id = id;
	}

	/**
	 * @return The label of the vertex
	 */
	public int getId() {
		return id;
	}
}
